package by.bsu.scs.db.dao;

// Generated 05.03.2011 11:02:55 by Hibernate Tools 3.4.0.CR1

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Example;

import by.bsu.scs.model.Discipline;
import by.bsu.scs.model.DisciplineStudentGroup;
import by.bsu.scs.model.Group;
import by.bsu.scs.model.User;
import by.bsu.scs.util.db.HibernateUtil;
import by.bsu.scs.util.manager.PropertyManager;

/**
 * Home object for domain model class DisciplineStudentGroup.
 * 
 * @see by.bsu.scs.model.DisciplineStudentGroup
 * @author Hibernate Tools
 */
public class DisciplineStudentGroupHome {

	public static final String STUDENTS_BY_INSTRUCTOR_ID = "getStudentsByInstructorId";
	public static final String INSTRUCTOR_ID = "instructorId";
	private static final Logger LOGGER = Logger
			.getLogger(DisciplineStudentGroupHome.class);

	private Session session = null;
	private Transaction transaction = null;

	public void persist(DisciplineStudentGroup transientInstance) {
		LOGGER.info("persisting DisciplineStudentGroup instance");
		session = HibernateUtil.openCurrentSession();
		try {
			transaction = session.beginTransaction();
			session.save(transientInstance);
			transaction.commit();
			LOGGER.info("persist successful");
		} catch (HibernateException e) {
			transaction.rollback();
			LOGGER.error("persist failed", e.getCause());
		}
	}

	public void attachDirty(DisciplineStudentGroup instance) {
		LOGGER.info("attaching dirty DisciplineStudentGroup instance");
		session = HibernateUtil.openCurrentSession();
		try {
			transaction = session.beginTransaction();
			session.saveOrUpdate(instance);
			transaction.commit();
			LOGGER.info("attach successful");
		} catch (HibernateException e) {
			transaction.rollback();
			LOGGER.error("attach failed", e.getCause());
		}
	}

	@SuppressWarnings("deprecation")
	public void attachClean(DisciplineStudentGroup instance) {
		LOGGER.info("attaching clean DisciplineStudentGroup instance");
		session = HibernateUtil.openCurrentSession();
		try {
			transaction = session.beginTransaction();
			session.lock(instance, LockMode.NONE);
			transaction.commit();
			LOGGER.info("attach successful");
		} catch (HibernateException e) {
			transaction.rollback();
			LOGGER.error("attach failed", e.getCause());
		}
	}

	public void delete(DisciplineStudentGroup persistentInstance) {
		LOGGER.info("deleting DisciplineStudentGroup instance");
		session = HibernateUtil.openCurrentSession();
		try {
			transaction = session.beginTransaction();
			session.delete(persistentInstance);
			transaction.commit();
			LOGGER.info("delete successful");
		} catch (HibernateException e) {
			transaction.rollback();
			LOGGER.error("delete failed", e.getCause());
		}
	}

	public DisciplineStudentGroup merge(DisciplineStudentGroup detachedInstance) {
		LOGGER.info("merging DisciplineStudentGroup instance");
		session = HibernateUtil.openCurrentSession();
		try {
			transaction = session.beginTransaction();
			DisciplineStudentGroup result = (DisciplineStudentGroup) session
					.merge(detachedInstance);
			transaction.commit();
			LOGGER.info("merge successful");
			return result;
		} catch (HibernateException e) {
			transaction.rollback();
			LOGGER.error("merge failed", e.getCause());
			return null;
		}
	}

	public DisciplineStudentGroup findById(int id) {
		LOGGER.info("getting DisciplineStudentGroup instance with id: " + id);
		session = HibernateUtil.openCurrentSession();
		try {
			transaction = session.beginTransaction();
			DisciplineStudentGroup instance = (DisciplineStudentGroup) session
					.get("by.bsu.scs.model.DisciplineStudentGroup", id);
			if (instance == null) {
				LOGGER.info("get successful, no instance found");
			} else {
				LOGGER.info("get successful, instance found");
			}
			transaction.commit();
			return instance;
		} catch (RuntimeException e) {
			transaction.rollback();
			LOGGER.error("get failed", e.getCause());
			return null;
		}
	}

	@SuppressWarnings("rawtypes")
	public List findByExample(DisciplineStudentGroup instance) {
		LOGGER.info("finding DisciplineStudentGroup instance by example");
		session = HibernateUtil.openCurrentSession();
		try {
			transaction = session.beginTransaction();
			Example example = Example.create(instance).excludeZeroes();
			List results = session
					.createCriteria("by.bsu.scs.model.DisciplineStudentGroup")
					.add(example).list();
			LOGGER.info("find by example successful, result size: "
					+ results.size());
			transaction.commit();
			return results;
		} catch (RuntimeException e) {
			transaction.rollback();
			LOGGER.error("find by example failed", e.getCause());
			return null;
		}
	}

	// ****************************Methods added***********************
	public List<User> getStudentsByInstructorId(User instructor) {
		// LOGGER.info("finding students by instructor id");
		// session = HibernateUtil.openCurrentSession();
		// try {
		// transaction = session.beginTransaction();
		// @SuppressWarnings("unchecked")
		// List<User> results = session
		// .getNamedQuery(STUDENTS_BY_INSTRUCTOR_ID)
		// .setInteger(INSTRUCTOR_ID, instructor.getUserId()).list();
		// LOGGER.info("find by example successful, result size: "
		// + results.size());
		// transaction.commit();
		// return results;
		// } catch (RuntimeException e) {
		// transaction.rollback();
		// LOGGER.error("find students by instructor id failed", e.getCause());
		// return null;
		// }
		return getStudentsByInstructorIdSQL(instructor);
	}

	public List<User> getStudentsByInstructorIdSQL(User instructor) {
		LOGGER.info("finding students by instructor id");
		session = HibernateUtil.openCurrentSession();
		try {
			transaction = session.beginTransaction();

			String sql = PropertyManager.getInstance().getProperty(
					PropertyManager.STUDENTS_BY_INSTRUCTOR_ID_SQL);
			Object[] params = { instructor.getUserId() };
			MessageFormat messageToFormat = new MessageFormat(sql);
			sql = messageToFormat.format(params);

			List results = session.createSQLQuery(sql).list();

			LOGGER.info("find successful, result size: " + results.size());
			transaction.commit();
			return parseUserData(results);
		} catch (RuntimeException e) {
			transaction.rollback();
			LOGGER.error("find students by instructor id failed", e.getCause());
			return null;
		}
	}

	public List<User> getStudentsByInstructorDisciplineGroupCourseSQL(
			User instructor, Discipline discipline, Group group) {
		LOGGER.info("finding students by instructor, discipline, group and course id");
		session = HibernateUtil.openCurrentSession();
		try {
			transaction = session.beginTransaction();

			String sql = PropertyManager
					.getInstance()
					.getProperty(
							PropertyManager.STUDENTS_BY_INSTRUCTOR_DISCIPLINE_GROUP_COURSE_SQL);

			Object[] params = { instructor.getUserId(),
					discipline.getDisciplineId(), group.getGroupNumber(),
					group.getCourseId().getCourseNumber() };
			MessageFormat messageToFormat = new MessageFormat(sql);
			sql = messageToFormat.format(params);

			List results = session.createSQLQuery(sql).list();

			LOGGER.info("find successful, result size: " + results.size());
			transaction.commit();
			return parseUserData(results);
		} catch (RuntimeException e) {
			transaction.rollback();
			LOGGER.error("find failed", e.getCause());
			return null;
		}
	}

	public List<User> getStudentsByInstructorGroupCourseSQL(User instructor,
			Group group) {
		LOGGER.info("finding students by instructor, group and course id");
		session = HibernateUtil.openCurrentSession();
		try {
			transaction = session.beginTransaction();

			String sql = PropertyManager.getInstance().getProperty(
					PropertyManager.STUDENTS_BY_INSTRUCTOR_GROUP_COURSE_SQL);

			Object[] params = { instructor.getUserId(), group.getGroupNumber(),
					group.getCourseId().getCourseNumber() };
			MessageFormat messageToFormat = new MessageFormat(sql);
			sql = messageToFormat.format(params);

			List results = session.createSQLQuery(sql).list();

			LOGGER.info("find successful, result size: " + results.size());
			transaction.commit();
			return parseUserData(results);
		} catch (RuntimeException e) {
			transaction.rollback();
			LOGGER.error("find failed", e.getCause());
			return null;
		}
	}

	public List<User> getStudentsByInstructorDisciplineCourseSQL(
			User instructor, Discipline discipline, Group group) {
		LOGGER.info("finding students by instructor, discipline, and course id");
		session = HibernateUtil.openCurrentSession();
		try {
			transaction = session.beginTransaction();

			String sql = PropertyManager
					.getInstance()
					.getProperty(
							PropertyManager.STUDENTS_BY_INSTRUCTOR_DISCIPLINE_COURSE_SQL);

			Object[] params = { instructor.getUserId(),
					discipline.getDisciplineId(),
					group.getCourseId().getCourseNumber() };
			MessageFormat messageToFormat = new MessageFormat(sql);
			sql = messageToFormat.format(params);

			List results = session.createSQLQuery(sql).list();

			LOGGER.info("find successful, result size: " + results.size());
			transaction.commit();
			return parseUserData(results);
		} catch (RuntimeException e) {
			transaction.rollback();
			LOGGER.error("find failed", e.getCause());
			return null;
		}
	}
	
	public List<User> getStudentsByInstructorDisciplineGroupSQL(
			User instructor, Discipline discipline, Group group) {
		LOGGER.info("finding students by instructor, discipline, and group id");
		session = HibernateUtil.openCurrentSession();
		try {
			transaction = session.beginTransaction();

			String sql = PropertyManager
					.getInstance()
					.getProperty(
							PropertyManager.STUDENTS_BY_INSTRUCTOR_DISCIPLINE_GROUP_SQL);

			Object[] params = { instructor.getUserId(),
					discipline.getDisciplineId(), group.getGroupNumber()};
			MessageFormat messageToFormat = new MessageFormat(sql);
			sql = messageToFormat.format(params);

			List results = session.createSQLQuery(sql).list();

			LOGGER.info("find successful, result size: " + results.size());
			transaction.commit();
			return parseUserData(results);
		} catch (RuntimeException e) {
			transaction.rollback();
			LOGGER.error("find failed", e.getCause());
			return null;
		}
	}

	public List<User> getStudentsByInstructorDisciplineSQL(
			User instructor, Discipline discipline) {
		LOGGER.info("finding students by instructor and discipline id");
		session = HibernateUtil.openCurrentSession();
		try {
			transaction = session.beginTransaction();

			String sql = PropertyManager
					.getInstance()
					.getProperty(
							PropertyManager.STUDENTS_BY_INSTRUCTOR_DISCIPLINE_SQL);

			Object[] params = { instructor.getUserId(),
					discipline.getDisciplineId()};
			MessageFormat messageToFormat = new MessageFormat(sql);
			sql = messageToFormat.format(params);

			List results = session.createSQLQuery(sql).list();
			
			LOGGER.info("find successful, result size: " + results.size());
			transaction.commit();
			return parseUserData(results);
		} catch (RuntimeException e) {
			transaction.rollback();
			LOGGER.error("find failed", e.getCause());
			return null;
		}
	}
	
	private List<User> parseUserData(List results) {
		List<User> userList = new ArrayList<User>();
		for (Object o : results) {
			Object[] userData = (Object[]) o;
			if(userData[0] != null){
				User user = new User();
				user.setUserId((Integer) userData[0]);
				user.setBsuId((Integer) userData[1]);
				user.setUserName((String) userData[2]);
				user.setUserSurname((String) userData[3]);
				user.setEmail((String) userData[4]);
				user.setUserRole(new UserRoleHome().findById((Integer) userData[5]));
				userList.add(user);
			}
		}
		return userList;
	}

}
